﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using System.Diagnostics;
using AssemblyInfo;
using Trav;

namespace WinController
{
    public partial class AppController : Form
    {
        //
        ///// File menu
        //

        private void fileMenu_DropDownOpening (object sender, EventArgs e)
        {
            fileMenuOpenFolder.Enabled  = !model.IsBusy;
            fileMenuCloseFolder.Enabled = !model.IsBusy && model.Tree != null;
            fileMenuSelectPlaylist.Enabled = !model.IsBusy && details.Items.Count > 0;
            fileMenuSaveSelection.Enabled = !model.IsBusy && details.SelectedItems.Count > 0;
        }


        private void fileMenuOpenFolder_Click (object sender, EventArgs e)
        {
            DialogResult result;
            string path;

            using (FolderBrowserDialog dialog = new FolderBrowserDialog())
            {
                result = dialog.ShowDialog();
                path = dialog.SelectedPath;
            }
            
            if (result == DialogResult.OK)
            {
                if (model.Tree != null)
                    model.CloseRoot ();

                model.OpenRootAsync (path);
            }
        }


        private void fileMenuCloseFolder_Click (object sender, EventArgs e)
        {
            model.CloseRoot ();
        }


        private void fileMenuSaveSelection_Click (object sender, EventArgs e)
        {
            DialogResult result;
            string fileName;

            using (SaveFileDialog dialog = new SaveFileDialog())
            {
                dialog.InitialDirectory = model.CurrentDir;
                dialog.Filter = "playlists (*.m3u)|*.m3u|All files (*.*)|*.*";
                result = dialog.ShowDialog();
                fileName = dialog.FileName;
            }

            if (result == DialogResult.OK)
                model.SaveSelectionToPlaylist (fileName, false);
        }


        private void fileMenuSelectPlaylist_Click (object sender, EventArgs e)
        {
            DialogResult result;
            string fileName;

            using (OpenFileDialog dialog = new OpenFileDialog())
            {
                dialog.Filter = "playlists (*.m3u)|*.m3u|All files (*.*)|*.*";
                result = dialog.ShowDialog();
                fileName = dialog.FileName;
            }

            if (result == DialogResult.OK)
                model.SelectFromPlaylist (fileName);
        }


        private void fileMenuAbout_Click (object sender, EventArgs e)
        {
            MessageBox.Show (this,
                About.Product + ": " + About.Description + "\r" + About.Copyright + "\r",
                "About Traveler v" + About.Version,
                MessageBoxButtons.OK, MessageBoxIcon.None, MessageBoxDefaultButton.Button1);
        }


        private void fileMenuExit_Click (object sender, EventArgs e)
        {
            Application.Exit ();
        }

        //
        ///// Edit menu
        //

        private void editMenu_DropDownOpening (object sender, EventArgs e)
        {
            if (model.IsBusy)
            {
                foreach (ToolStripItem item in editMenu.DropDownItems)
                    if (item is ToolStripMenuItem)
                        item.Enabled = false;
                return;
            }

            editMenuCopy.Enabled = model.Detail.View.SelectedCount > 0;
            editMenuDelete.Enabled = model.Detail.View.SelectedCount > 0;
            editMenuSelectAll.Enabled = model.Detail.View.Count > 0;
            editMenuInvert.Enabled = model.Detail.View.SelectedCount > 0;
            editMenuSelectDuplicates.Enabled = model.Detail.View.Count >= 2;
            editMenuNext.Enabled = model.Detail.View.SelectedCount > 0;

            if (!model.HasCurrentDir)
                editMenuPaste.Enabled = false;
            else
            {
                object fd = Clipboard.GetData (DataFormats.FileDrop);
                if (fd != null)
                {
                    string[] sx = (string[]) fd;
                    if (sx.Length > 0)
                        editMenuPaste.Enabled = true;
                }
            }
        }


        // For items with accelerators that may asynchronously become valid.
        private void editMenu_DropDownClosed (object sender, EventArgs e)
        {
            editMenuSelectAll.Enabled = true;
            editMenuSelectDuplicates.Enabled = true;
            editMenuNext.Enabled = true;
            editMenuPaste.Enabled = true;
        }


        private void editMenuCopy_Click (object sender, EventArgs e)
        {
            string[] files = new string[model.Detail.View.SelectedCount];
            int index = 0;

            foreach (string fullName in model.Detail.View.SelectedFullNames)
                files[index++] = fullName;

            DataObject j = new DataObject (DataFormats.FileDrop, files);
            Clipboard.SetDataObject (j);
        }


        private void editMenuPaste_Click (object sender, EventArgs e)
        {
            object dropped = Clipboard.GetData (DataFormats.FileDrop);
            if (dropped != null)
            {
                string[] sourceFiles = (string[]) dropped;
                model.CopyFiles (sourceFiles, model.CurrentDir);
            }
        }


        private void editMenuDelete_Click (object sender, EventArgs e)
        {
            model.DeleteSelectedFiles ();
        }


        private void editMenuSelectAll_Click (object sender, EventArgs e)
        {
            SupressStatusUpdates = true;
            for (int di = 0; di < details.Items.Count; ++di)
                details.Items[di].Selected = true;
            SupressStatusUpdates = false;
            details.Select ();
            model.ShowStatus (null);
        }


        private void editMenuSelectNone_Click (object sender, EventArgs e)
        {
            SupressStatusUpdates = true;
            for (int di = 0; di < details.Items.Count; ++di)
                details.Items[di].Selected = false;
            SupressStatusUpdates = false;
            details.Select ();
            model.ShowStatus (null);
        }


        private void editMenuInvert_Click (object sender, EventArgs e)
        {
            SupressStatusUpdates = true;
            for (int di = 0; di < details.Items.Count; ++di)
                details.Items[di].Selected = !details.Items[di].Selected;
            SupressStatusUpdates = false;
            details.Select ();
            model.ShowStatus (null);
        }


        private void editMenuSelectDuplicates_Click (object sender, EventArgs e)
        {
            SupressStatusUpdates = true;
            model.SelectDuplicates ();
            SupressStatusUpdates = false;
            model.ShowStatus (null);
        }


        // Scroll detail control so that next unseen selection is visible.
        // This method is a control enhancement only.
        private void editMenuNext_Click (object sender, EventArgs e)
        {
            ListViewItem topItem = details.TopItem;
            if (topItem == null)
                return;

            int contentHeight = details.Size.Height - topItem.Position.Y;
            int lastViewedIndex = 0;

            for (; lastViewedIndex < details.Items.Count; ++lastViewedIndex)
            {
                Point p = details.Items[lastViewedIndex].Position;
                if (p.Y >= contentHeight)
                    break;
            }

            --lastViewedIndex;
            if (lastViewedIndex >= 0)
                for (int si = 0; si < details.SelectedItems.Count; ++si)
                    if (details.SelectedItems[si].Index > lastViewedIndex)
                    {
                        details.Items[details.SelectedItems[si].Index].EnsureVisible ();
                        details.Select ();
                        return;
                    }
        }

        //
        ///// Folder menu
        //

        private void folderMenu_DropDownOpened (object sender, EventArgs e)
        {
            folderMenuExpandAll.Enabled = !model.IsBusy && model.Tree != null;
            folderMenuNew.Enabled = !model.IsBusy && model.HasCurrentDir;
        }


        private void folderMenuExpandAll_Click (object sender, EventArgs e)
        {
            folders.ExpandAll ();
        }


        private void folderMenuNew_Click (object sender, EventArgs e)
        {
            TreeNode node = folders.SelectedNode;

            if (node != null)
            {
                TreeNode newNode = node.Nodes.Add ("");
                newNode.EnsureVisible ();
                folders.LabelEdit = true;
                newNode.BeginEdit ();
            }
        }

        //
        ///// Detail main menu
        //

        private void detailMenu_DropDownOpened (object sender, EventArgs e)
        {
            detailMenuShowSubfolders.Checked = model.Detail.IsSubfoldersShown;
        }


        private void detailMenuArrangeBySelected_Click (object sender, EventArgs e)
        {
            sortDetailsColumn (-1, null);
        }


        private void detailMenuArrangeByName_Click (object sender, EventArgs e)
        {
            sortDetailsColumn (ColumnBaseName, "S");
        }

        private void detailMenuArrangeByType_Click (object sender, EventArgs e)
        {
            sortDetailsColumn (-2, null);
        }


        private void detailMenuShowSubfolders_Click (object sender, EventArgs e)
        {
            model.ShowSubfolders (!model.Detail.IsSubfoldersShown);
        }

        //
        ///// Detail context menu
        // 

        private void detailContext_Opening (object sender, CancelEventArgs e)
        {
            bool enable = !model.IsBusy && model.Detail.View.SelectedCount > 0;
            detailContextOpen.Enabled = enable;
            detailContextSelectFrom.Enabled = enable;

        }

        private void detailContextOpen_Click (object sender, EventArgs e)
        {
            model.LaunchSelections ();
        }

        private void detailContextSelectFrom_Click (object sender, EventArgs e)
        {
            var selectionFullName = new List<string> ();

            foreach (string f in model.Detail.View.SelectedFullNames)
                selectionFullName.Add (f);

            model.Detail.View.SelectNone ();

            foreach (string f in selectionFullName)
                model.SelectFromPlaylist (f);
        }
    }
}
